// SPDX-License-Identifier: GPL-2.0
/*
 * lombo_dmic.c - Common dmic for LomboTech SoCs
 *
 * Copyright (C) 2016-2018, LomboTech Co.Ltd.
 * Author: lomboswer <lomboswer@lombotech.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <trace/events/asoc.h>
#include <mach/csp.h>
#include <mach/debug.h>
#include <mach/common.h>

#undef  MOD_NAME
#define MOD_NAME "LOMBO_DMIC"

/* sample_rate supportted by this dmic driver */
#define LOMBO_DMIC_RATES \
	(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
	SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
	SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)

/* sample_bits supportted by this dmic driver */
#define LOMBO_DMIC_FORMAT \
	(SNDRV_PCM_FORMAT_S16_LE | SNDRV_PCM_FORMAT_S32_LE)

/* define dai driver */
static struct snd_soc_dai_driver lombo_dmic_dai = {
	.name	  = "dmic_dai",
	.capture = {
		.stream_name  = "Capture",
		.channels_min = 1,
		.channels_max = 8,
		.rates        = LOMBO_DMIC_RATES,
		.formats      = LOMBO_DMIC_FORMAT,
	},
};

static const struct snd_soc_component_driver soc_component_dmic = {
	.name			= "lombo_dmic_component",
	.idle_bias_on		= 1,
	.use_pmdown_time	= 1,
	.endianness		= 1,
	.non_legacy_dai_naming	= 1,
};

static int lombo_dmic_probe(struct platform_device *pdev)
{
	int err;
	u32 chans;
	struct snd_soc_dai_driver *dai_drv = &lombo_dmic_dai;

	dev_info(&pdev->dev, "Entered %s\n", __func__);
	/* register dmic codec_dai */
	if (pdev->dev.of_node) {
		err = of_property_read_u32(pdev->dev.of_node,
			"num-channels", &chans);
		if (err && (err != -EINVAL))
			return err;
		dev_info(&pdev->dev, "get dmic chan num %d\n", chans);
		if (!err) {
			if (chans < 1 || chans > 8)
				return -EINVAL;

			dai_drv = devm_kzalloc(&pdev->dev, sizeof(*dai_drv),
				GFP_KERNEL);
			if (!dai_drv)
				return -ENOMEM;

			memcpy(dai_drv, &lombo_dmic_dai, sizeof(*dai_drv));
			dai_drv->capture.channels_max = chans;
		}
	}
	return devm_snd_soc_register_component(&pdev->dev,
			&soc_component_dmic, dai_drv, 1);
}

static const struct of_device_id lombo_dmic_match[] = {
	{ .compatible = "lombo, dmic", },
	{ /* end */},
};

static struct platform_driver lombo_codec_driver = {
	.driver = {
		.name = "lombo-dmic",
		.owner = THIS_MODULE,
		.of_match_table = of_match_ptr(lombo_dmic_match),
	},
	.probe	= lombo_dmic_probe,
};

module_platform_driver(lombo_codec_driver);

/* Module information */
MODULE_AUTHOR("lomboswer <lomboswer@lombotech.com>");
MODULE_DESCRIPTION("lombo Dmic");
MODULE_LICENSE("GPL");

